#include "tabmanager.h"
#include <iostream>
#include <QDesktopServices>

TabManager::TabManager(MainWindow* mainWindow) : mainWindow(mainWindow)
{
    /**** tools分支新增 ****/
    toolsSettings = new ToolsSettings(this);
    compilerOption = new CompilerOptions(this);
    codeEditor = new CodeEditor(this, mainWindow);
    connect(toolsSettings, &ToolsSettings::accepted, this, &TabManager::on_toolsSettingAccepted);
    /*********************/
    text1 = new CodeEditor(this, mainWindow);
    textEditor = new TextEditor(this);
    codeBuilding = new CodeBuilding(this);
    backForward = new BackForward(this);
    syntaxHighlighter = new SyntaxHighlighter(text1->document());

}
void TabManager::on_tab_changed(int index)
{
    //std::cout << "change" << std::endl;
    if(!mainWindow->tabWidget->widget(index))
    {
        mainWindow->file_save->setEnabled(false);
        mainWindow->file_save_as->setEnabled(false);
        text1 = new CodeEditor(this, mainWindow);
        return;
    }
    mainWindow->file_save->setEnabled(true);
    mainWindow->file_save_as->setEnabled(true);
    QWidget* currentWidget = mainWindow->tabWidget->widget(index);
    text1 = qobject_cast<CodeEditor*>(currentWidget);
    /***** tools *****/
    on_toolsSettingAccepted();
    //codeEditor->loadBackgroundImage();
    /*****************/
    tab_index = index;
    filename = mainWindow->tabWidget->widget(tab_index)->property("name").toString();
    connect(text1, &QPlainTextEdit::textChanged, backForward, &BackForward::on_text_changed_back);
    connect(text1, &QPlainTextEdit::textChanged, textEditor, &TextEditor::on_text_changed_find);
    connect(text1, &QPlainTextEdit::textChanged, this, &TabManager::on_text_changed_file);
    // 更新filename
    filename = text1->filenameThis;
    //跳转标签页时获取当前标签页的索引值并赋值给变量tab_index，然后将该标签页的文本赋值给text1以供用户修改
    //std::cout << filename.toLocal8Bit().toStdString() << std::endl;
    mainWindow->terminal->cdFilePath(filename); // 终端跳到当前代码的位置
}
void TabManager::on_close_tab(int index)
{
    //std::cout << "close" << std::endl;
    if(text1->objectName() == "changed")
    {
        int result = QMessageBox::question(this, "提示", "要保存该文件吗？", QMessageBox::Yes | QMessageBox::No);
        if (result == QMessageBox::Yes)
        {
            on_save();
        }
    }
    QWidget *widget_remove = mainWindow->tabWidget->widget(index);
    mainWindow->tabWidget->removeTab(index);
    delete widget_remove;
    tab_index = std::min(index, mainWindow->tabWidget->count() - 1);
    if(tab_index >= 0) {
        filename = qobject_cast<CodeEditor*>(mainWindow->tabWidget->widget(tab_index))->filenameThis;
        mainWindow->terminal->cdFilePath(filename); // 终端跳到当前代码的位置
    } else
        filename = "";
    //关闭标签页时同时删掉该标签页的历史文本列表
    if(mainWindow->tabWidget->count() == 0) {
        mainWindow->build->setEnabled(false); // 失能编译
        mainWindow->buildAction->setEnabled(false);
        mainWindow->buildAndRunAction->setEnabled(false);
    }
}
void TabManager::on_newfile()
{
    //std::cout << "new" << std::endl;
    CodeEditor* newTextEdit = new CodeEditor(this, mainWindow);
    mainWindow->tabWidget->addTab(newTextEdit, "新建文件");
    newTextEdit->setObjectName("unchanged");
    QList<QString> tab_back_text;
    tab_back_text.append(newTextEdit->toPlainText());
    back_text.append(tab_back_text);
    //建立新的文本newTextEdit放在标签页中，tab_back_text为该标签页的历史文本（为撤销操作服务）
    tab_index = mainWindow->tabWidget->count() - 1;
    mainWindow->tabWidget->setCurrentIndex(mainWindow->tabWidget->count() - 1); // 跳转到新建的文件
    if(mainWindow->tabWidget->count() > 0) {
        mainWindow->build->setEnabled(true); // 使能编译
        mainWindow->buildAction->setEnabled(true);
        mainWindow->buildAndRunAction->setEnabled(true);
    }
}
void TabManager::on_open()
{
   // std::cout << "open" << std::endl;
    QString filename1 = filename; // 文件路径备份
    filename = QFileDialog::getOpenFileName();//打开一个标准文件对话框，返回用户选择的路径+文件名
    QString filename_ = filename;

    if (filename.isEmpty()) {
        filename = filename1;  // 恢复
        return;
    }
    /* 转utf8以支持中文路径 */
    QTextCodec *code_UTF8 = QTextCodec::codecForName("UTF-8");
    QString filePath_UTF8 = QString::fromStdString(code_UTF8->fromUnicode(filename).data());

    QByteArray byteArray = filePath_UTF8.toLocal8Bit();
    const char* filePathCN = byteArray.constData(); // 使用filePathCN

    QString content;
    FILE *p = fopen(filePathCN, "r");
    if (p == NULL)
    {
        QMessageBox::information(this, "错误", "打开文件失败");//如果打开文件失败，那么提醒用户
    }
    else
    {
        while(!feof(p))
        {
            char buf[1024] = {0};
            fgets(buf, sizeof(buf), p);
            content +=buf;//将buf的内容追加到content的后面
        }
        fclose(p);
        CodeEditor* newTextEdit = new CodeEditor(this, mainWindow);
        newTextEdit->setPlainText(content);
        text1 = newTextEdit;//将QString里的字符串放入到text1里面
        text1->filenameThis = filename;  // 保存文件路径和文件名
        QFileInfo fileInfo(filename);
        mainWindow->tabWidget->addTab(newTextEdit, fileInfo.fileName());
        filename = filename_;
        mainWindow->tabWidget->widget(tab_index)->setProperty("name",filename);
        newTextEdit->setObjectName("unchanged");
        QList<QString> tab_back_text;
        tab_back_text.append(newTextEdit->toPlainText());
        back_text.append(tab_back_text);
        tab_index = mainWindow->tabWidget->count() - 1;
        mainWindow->tabWidget->setCurrentIndex(mainWindow->tabWidget->count() - 1);
        if(mainWindow->tabWidget->count() > 0) {
            mainWindow->build->setEnabled(true); // 使能编译
            mainWindow->buildAction->setEnabled(true);
            mainWindow->buildAndRunAction->setEnabled(true);
        }
    }

}
void TabManager::on_exit()
{
    exit(0);
}
bool TabManager::on_save()
{
    if (filename.isEmpty())
    {
        return on_save_as();
    }

    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QByteArray byteArray = filename.toLocal8Bit();
    const char* filePathCN = byteArray.constData();

    FILE *p = fopen(filePathCN, "w");
    if (p == NULL)
    {
        QMessageBox::critical(this, "错误", "无法保存文件。");
        return false;
    }
    else
    {
        CodeEditor* currentTextEdit = qobject_cast<CodeEditor*>(mainWindow->tabWidget->currentWidget());
        if (currentTextEdit)
        {
            QTextStream out(p);
            out.setCodec(codec);
            out << currentTextEdit->toPlainText();
        }
        fclose(p);
        text1->setObjectName("unchanged");
        //使用objectname属性来标记一个文件保存与未保存
    }
    return true;
}

bool TabManager::on_save_as()
{
    QFileInfo fileInfoNow(filename);
    QString filePath;
    if(filename == "")
        filePath = QFileDialog::getSaveFileName(nullptr, "另存为", "未命名", "C语言源文件(*.c);;C++语言源文件(*.cpp);;文本文件 (*.txt);;所有文件 (*)");
    else
        filePath = QFileDialog::getSaveFileName(nullptr, "另存为", fileInfoNow.fileName(), "C语言源文件(*.c);;C++语言源文件(*.cpp);;文本文件 (*.txt);;所有文件 (*)");
    if (!filePath.isEmpty())
    {
        QTextCodec *codec = QTextCodec::codecForName("UTF-8");
        QByteArray byteArray = filePath.toLocal8Bit();
        const char* filePathCN = byteArray.constData();

        FILE *p = fopen(filePathCN, "w");
        if (p == NULL)
        {
            QMessageBox::critical(nullptr, "错误", "无法保存文件。");
            return false;
        }
        else
        {
            CodeEditor* currentTextEdit = qobject_cast<CodeEditor*>(mainWindow->tabWidget->currentWidget());
            if (currentTextEdit)
            {
                QTextStream out(p);
                out.setCodec(codec);
                out << currentTextEdit->toPlainText();
            }
            fclose(p);
            filename = filePath;
            QFileInfo fileInfo(filename);
            text1->setObjectName("unchanged");
            text1->filenameThis = filename;
            // 另存为后更新文件名称
            //mainWindow->tabWidget->addTab(text1, fileInfo.fileName());
            mainWindow->tabWidget->setCurrentIndex(tab_index);
            mainWindow->tabWidget->widget(tab_index)->setProperty("name",filename);
            mainWindow->tabWidget->setTabText(tab_index, fileInfo.fileName());
            mainWindow->terminal->cdFilePath(filename); // 终端跳到当前代码的位置
        }
        return true;
    } else {
        return false;
    }
}
void TabManager::on_text_changed_file()
{
    text1->setObjectName("changed");
}

void TabManager::onOpenDoc()
{
    // 获取当前程序所在目录
       //QString currentPath = QDir::currentPath();
       // 构建说明书文件的路径
       //QString manualPath = currentPath + "/instruction.docx";
       // 打开说明书文件
    QDesktopServices::openUrl(QUrl::fromLocalFile("./resource/CAurora用户手册.pdf"));
}
TabManager::~TabManager()
{
    delete syntaxHighlighter;
    delete text1;
    delete textEditor;
    delete codeBuilding;
    delete backForward;
    delete toolsSettings;

    // 遍历并删除所有可能残留的 CodeEditor 实例（如果有的话）
    for (int i = 0; i < mainWindow->tabWidget->count(); ++i)
    {
        QWidget *widget = mainWindow->tabWidget->widget(i);
        CodeEditor *codeEditor = qobject_cast<CodeEditor*>(widget);
        if (codeEditor)
        {
            delete codeEditor;
        }
    }
}

/**** tools分支新增 ****/
void TabManager::on_toolsSettingAccepted() {
    //std::cout << "OnNew: " << toolsSettings->currentFont.pixelSize() << std::endl;
    text1->loadBackgroundImage(toolsSettings->imagePath, toolsSettings->opacity);
    QString styleSheet = QString(
        "QPlainTextEdit {"
        "border-image: url(%1) 0 0 0 0 stretch stretch;"
        "}"
    ).arg(toolsSettings->imagePath);
    text1->setStyleSheet(styleSheet);
    if(toolsSettings->currentTheme == "Light"){
        // 获取当前光标位置
        QTextCursor cursor = text1->textCursor();
        cursor.select(QTextCursor::Document); // 选择整个文档
        QTextCharFormat format;
        format.setForeground(QColor(40, 44, 52)); // 设置字体颜色
        cursor.mergeCharFormat(format);
        text1->mergeCurrentCharFormat(format);
        text1->syntaxHighlighter->setupRule();
    }
    else {
        // 获取当前光标位置
        QTextCursor cursor = text1->textCursor();
        cursor.select(QTextCursor::Document); // 选择整个文档
        QTextCharFormat format;
        format.setForeground(QColor("white")); // 设置字体颜色
        cursor.mergeCharFormat(format);
        text1->mergeCurrentCharFormat(format);
        text1->syntaxHighlighter->setupRuleDark();
    }
    text1->setFont(toolsSettings->currentFont);
    text1->syntaxHighlighter->rehighlight();
}
/*********************/
